﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

namespace TreeLayoutPlayground
{
    internal abstract class LayoutEngine
    {
        public int GapSize { get; set; }
        public int HalfGap { get { return GapSize / 2; } }

        public abstract void Layout(Tree tree);

        public double EvaluateArea(Tree tree)
        {
            int overall = tree.OverallSize.Width * tree.OverallSize.Height;
            return GetUsedArea(tree) / (double)overall;
        }

        private int GetUsedArea(Tree tree)
        {
            return tree.Children.Aggregate(tree.MyBox.Width * tree.MyBox.Height,
                (sum, t) => { return sum + GetUsedArea(t); });
        }

        public double EvaluateLines(Tree tree)
        {
            double score = 0;
            int num = 0;
            Queue<Tree> work = new Queue<Tree>();
            work.Enqueue(tree);

            do
            {
                Tree cur = work.Dequeue();
                Point bc = cur.GetBotCenter(Size.Empty);
                num += cur.NumberOfChildren;
                foreach (Tree c in cur.Children)
                {
                    Point tc = c.GetTopCenter(c.MyRelativeTranslation);
                    if (bc.Y == tc.Y) { return double.PositiveInfinity; }

                    double slope = (bc.X - tc.X) / (bc.Y - tc.Y);
                    score += Math.Abs(slope);
                    work.Enqueue(c);
                }
            } while (work.Count > 0);

            if (num == 0) { return 0; }
            return score / num;
        }
    }
}